package com.next

import grails.transaction.Transactional
import org.springframework.security.access.annotation.Secured

import static org.springframework.http.HttpStatus.*

@Secured(['ROLE_ADMINISTRATOR', 'ROLE_COMPANY_ADMINISTRATOR', 'ROLE_COMPANY_USER'])
@Transactional(readOnly = true)
class AssetController
{

    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
    def springSecurityService
    def exportService
    def subscribeService

    def index(Integer max)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def assetList = Asset.findAll("from Asset where user.username = '${username}'", [max: params.max ?: 10, offset: params.offset ?: 0])
        def count = Asset.executeQuery("select count(id) from Asset where user.username = '${username}'")

        respond assetList, model: [assetCount: count[0]]
    }

    def show(Asset asset)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        def attachmentList = Attachment.findAll("from Attachment where asset.id = ?", [asset.id])
        def appointmentList = Activity.findAll("from Activity where asset.id = ? and type.id = ?", [asset.id, ActivityType.find("from ActivityType where name = 'Appointment'")?.id])
        def taskList = Activity.findAll("from Activity where asset.id = ? and type.id = ?", [asset.id, ActivityType.find("from ActivityType where name = 'Task'")?.id])
        def issueList = Issue.findAll("from Issue where asset.id = ?", [asset.id])
        def noteList = Note.findAll("from Note where asset.id = ?", [asset.id])
        def teamList = AssetTeam.findAll("from AssetTeam where asset.id = ?", [asset.id])
        def flexFieldInstanceList = FlexFieldInstance.findAll("from FlexFieldInstance where asset.id = ?", [asset.id])
        def follow = Follow.findByAssetAndUser(asset, user)
        def workflowInstanceList = WorkflowInstance.findAllByAsset(asset)
        respond asset, model: [attachmentList: attachmentList, appointmentList: appointmentList, taskList: taskList, issueList: issueList, noteList: noteList, teamList: teamList, flexFieldInstanceList: flexFieldInstanceList, teamName: 'assetTeam', follow: follow, workflowInstanceList: workflowInstanceList]
    }

    def create()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        def targetUri = request.getHeader("referer")
        respond new Asset(params), model: [user: user, targetUri: targetUri]
    }

    @Transactional
    def save(Asset asset)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (asset == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (asset.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond asset.errors, model: [user: user, targetUri: params['targetUri']], view: 'create'
            return
        }

        asset.save flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'asset.label', default: 'Asset'), asset.id])
                // redirect asset
                redirect uri: params['targetUri']
            }
            '*' { respond asset, [status: CREATED] }
        }
    }

    def edit(Asset asset)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        TeamRole editTeamRole = TeamRole.findByName('Edit')
        AssetTeam assetTeam = AssetTeam.findByAssetAndUser(asset, user)

        if (asset?.user?.id == user?.id || assetTeam?.teamRole?.id == editTeamRole?.id)
        {
            respond asset, model: [user: user]
        }
        else
        {
            flash.message = "没有编辑权限"
            respond asset, view: 'show'
        }
    }

    @Transactional
    def update(Asset asset)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (asset == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (asset.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond asset.errors, model: [user: user], view: 'edit'
            return
        }

        asset.save flush: true
        subscribeService.sendSubscribe asset

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'asset.label', default: 'Asset'), asset.id])
                redirect asset
            }
            '*' { respond asset, [status: OK] }
        }
    }

    @Transactional
    def delete(Asset asset)
    {

        if (asset == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        asset.delete flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'asset.label', default: 'Asset'), asset.id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NO_CONTENT }
        }
    }

    protected void notFound()
    {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'asset.label', default: 'Asset'), params.id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NOT_FOUND }
        }
    }

    def searchAsset()
    {
        def username = springSecurityService?.getPrincipal()?.username
        String code = params["code"]
        String name = params["name"]

        String sql = "from Asset as u where u.user.username = '${username}'"
        if (name)
        {
            sql += " and u.name like '%${name}%'"
        }
        if (code)
        {
            sql += " and u.code like '%${code}%'"
        }
        String countSql = "select count(u.id) " + sql
        sql += " order by u.modifiedDate desc"

        def list = Asset.findAll(sql, [max: params.max ?: 10, offset: params.offset ?: 0])
        def count = Asset.executeQuery(countSql)

        respond list, model: [assetCount: count[0], params: params], view: 'index'
    }

    def exportAsset()
    {
        def username = springSecurityService?.getPrincipal()?.username
        String code = params["code"]
        String name = params["name"]

        String sql = "from Asset as u where u.user.username = '${username}'"
        if (name)
        {
            sql += " and u.name like '%${name}%'"
        }
        if (code)
        {
            sql += " and u.code like '%${code}%'"
        }
        String countSql = "select count(u.id) " + sql
        sql += " order by u.modifiedDate desc"

        def list = Asset.findAll(sql)
        def count = Asset.executeQuery(countSql)

        if (params?.f && params.f != "html")
        {
            response.contentType = grailsApplication.config.grails.mime.types[params.f]
            response.setHeader("Content-disposition", "attachment; filename=asset.${params.extension}")
            List fields = ["name", "code", "status.name", "product.name", "account.name", "contact.fullName", "quantity", "purchaseDate", "installDate", "usageEndDate", "competitorAsset", "description", "createdDate", "modifiedDate"]
            Map labels = ["name": "资产名称", "code": "序列号", "status.name": "资产状态", "product.name": "产品", "account.name": "客户", "contact.fullName": "联系人", "quantity": "数量", "purchaseDate": "采购时间", "installDate": "安装时间", "usageEndDate": "停用时间", "competitorAsset": "竞争对手的设备", "description": "备注", "createdDate": "创建时间", "modifiedDate": "修改时间"]
            exportService.export(params.f, response.outputStream, list, fields, labels, [:], [:])
        }
    }
}
